package com.qf;

import com.qf.service.GoodService;
import com.qf.service.OrderService;
import com.qf.service.ProductService;
import com.qf.service.UserService;
import com.qf.util.ResponseUtil;
import com.qf.vo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.*;

/**
 * @author sunyamei
 * @version V1.0
 * @Project javase2203
 * @Package com.qf.controller
 * @Description:
 * @Date 2022/7/26 11:29
 */
@RequestMapping("/dashboard")
@CrossOrigin("*")
@RestController
public class IndexController {

      @Autowired
    private UserService userService;

      @Autowired
    private GoodService goodService;

      @Autowired
    private ProductService productService;

      @Autowired
    private OrderService orderService;


    /**
     * 首页统计数据
     * 用户量,商品量,货品量,订单量
     * @return
     */
    @GetMapping("")
      public  Object index(){

        //1:调用统计
        int userCount = userService.userCount();
        int goodCount = goodService.goodCount();
        int productCount = productService.productCount();
        int orderCount = orderService.orderCount();

        //2:封装结果数据返回
      Map<String, Integer> data = new HashMap<>();
      data.put("goodsTotal",goodCount);
      data.put("userTotal",userCount);
      data.put("productTotal",productCount);
      data.put("orderTotal",orderCount);

      return ResponseUtil.ok(data);
    }

    /**
     * 首页统计图表
     * categorySell : 商品分类和对应分类的销售额
     * orderAmts : 日期和对应的订单总额, 订单笔数
     * userOrderCnt : 日期对应的用户数和订单数
     * @return
     */
    @GetMapping("/chart")
    public  Object chart(){

        //1:查询数据库统计日期和用户的增长量
        List<DayStatis> userCnts = userService.userCnts();

        //2:查询数据库统计商品分类和对应分类的销售额
        List<CategorySellAmts> categoryCnts = orderService.categorySellCount();

        //3:查询数据库统计日期和对应的订单总额,订单笔数
        List<DayStatis> orderCnts = orderService.orderAmts();

        //4:封装日期,用户增长量,订单量vo view Object
        UserOrderCntVo userOrderCntVo = new UserOrderCntVo();

        //日期,整合了用户统计集合和订单统计集合中的所有日期
        String[] dayArry = mergeDayData(userCnts, orderCnts);
        userOrderCntVo.setDayData(dayArry);

        //用户增长量
        int[] userCntArry = fetchCnt(dayArry, userCnts);
        userOrderCntVo.setUserCnt(userCntArry);
        //订单量
        int[] orderArray= fetchCnt(dayArry, orderCnts);
        userOrderCntVo.setOrderCnt(orderArray);

        //5. 封装日期以及对应的订单金额, 订单笔数
        OrderAmtsVo orderAmtsVo = fetchOrderAmts(orderCnts);

        //6. 封装商品分类和对应分类的销售额
        CategorySellVo categorySellVo = fetchCategorySell(categoryCnts);

        //7. 将所有的vo封装到一个HashMap中
        Map<String, Object> data = new HashMap<>();
        data.put("categorySell", categorySellVo);
        data.put("orderAmts", orderAmtsVo);
        data.put("userOrderCnt", userOrderCntVo);

        //8. 返回结果
        return ResponseUtil.ok(data);


    }


    /**
     * 合并去重用户统计结果日期和订单统计结果日期
     * @param userCnts 统计日期和用户的增长量
     * @param orderCnts 统计日期和对应的订单总额,订单笔数
     * @return
     */
    private  String[] mergeDayData(List<DayStatis> userCnts,List<DayStatis> orderCnts){
        //1:设置set集合,用于过滤重复的日期
        Set<String> daySet = new HashSet<>();
        //2:遍历用户和日期的数据集合
        for (DayStatis userCnt : userCnts) {
            daySet.add(userCnt.getDayStr());
        }
        //3:遍历订单和日期的数据集合
        for (DayStatis orderCnt : orderCnts) {
            daySet.add(orderCnt.getDayStr());
        }
        //4:将set集合中的日期,转换为list,因为set无需,list有序,日期需要排序
       List<String> dayList = new ArrayList<>(daySet);
        //5:对list中的日期进行排序
        Collections.sort(dayList);
        //6:将日期转换成数组返回,数组也是有序的
        return  dayList.toArray(new String[0]);

    }

    /**
     * 根据日期获取用户增长量或者订单数量
     * @param dayArry 日期(整合了用户统计结果和订单统计结果的完整日期)
     * @param statisCount 可能是用户增长量统计数据也可能是订单数量统计数据
     * @return
     */
    private  int[] fetchCnt(String[] dayArry,List<DayStatis> statisCount){

        //1:声明数组用来存放统计的量,长度和日期个数相等
        int[] cnts =new int[dayArry.length];

        //2:遍历日期集合
        for (int i = 0; i < dayArry.length; i++) {
            //获取当前索引位置的日期
            String dayStr = dayArry[i];

            //3:遍历统计的日期和用户量也是订单量集合
            for (DayStatis dayStatis : statisCount) {
                //4:遍历过程中找到对应的日期数据
                if(dayStr.equals(dayStatis.getDayStr())){
                    cnts[i]=dayStatis.getCnts();
                    break;
                }
            }

        }
            return  cnts;

    }
    /**
     * 封装日期, 订单量, 订单金额集合
     * @return
     */
    public OrderAmtsVo fetchOrderAmts(List<DayStatis> orderCnts) {
        //1. 创建封装的vo
        OrderAmtsVo vo = new OrderAmtsVo();

        //声明用来存放集合元素个数的变量
        int size = 0;

        //2. 判断如果集合不为空, 获取集合大小
        if (orderCnts != null && orderCnts.size() > 0) {
            size = orderCnts.size();
        }

        //3. 声明存放日期的集合, 存放订单量的集合, 存放订单金额的集合
        String[] dayArray = new String[size];
        BigDecimal[] orderAmtData = new BigDecimal[size];
        int[] orderCntData = new int[size];

        //4. 遍历集合将对应的元素存储到对应的位置上
        for (int i = 0; i < orderCnts.size(); i++) {
            dayArray[i] = orderCnts.get(i).getDayStr();
            orderAmtData[i] = orderCnts.get(i).getAmts();
            orderCntData[i] = orderCnts.get(i).getCnts();
        }

        //5. 将数据存储到vo中
        vo.setDayData(dayArray);
        vo.setOrderAmtData(orderAmtData);
        vo.setOrderCntData(orderCntData);

        return vo;
    }

    /**
     * 封装对应的分类和销售额数据
     * @param categoryCnts
     * @return
     */
    private CategorySellVo fetchCategorySell(List<CategorySellAmts> categoryCnts) {

        //1. 声明封装的vo对象
        CategorySellVo vo = new CategorySellVo();

        //2. 声明用来存储分类名称的数组
        int size = 0;
        if (categoryCnts != null && categoryCnts.size() > 0) {
            size = categoryCnts.size();
        }
        String[] nameArray = new String[size];

        //3. 遍历集合提取分类名字数据
        for (int i = 0; i < categoryCnts.size(); i++) {
            nameArray[i] = categoryCnts.get(i).getName();
        }

        //4. 封装vo
        vo.setCategoryNames(nameArray);
        vo.setCategorySellData(categoryCnts);
        return vo;
    }
}
